﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;

using BlueCMS.Core.Data;
using BlueCMS.Core.Data.Query.Clauses;
using BlueCMS.Core.Data.Query.Columns;
using BlueCMS.Core.Data.Query.Conditions;
using BlueCMS.Core.Data.Query.Tables;
using BlueCMS.Core.Providers;

namespace BlueCMS.Core.Data.Query.Generator
{
    public abstract partial class QueryGeneratorBase
    {
        public virtual string ProcessSelectQuery(SelectClause select, FromClause from, WhereClause where, GroupByClause groupBy, HavingClause having, OrderByClause orderBy, bool distinct, int limit, int offset, Dictionary<string, DbParameter> parameters)
        {
            StringBuilder sb = new StringBuilder();

            GenerateSelectStatement(select, distinct, offset, limit, sb);
            GenerateFromStatement(from, sb, parameters);
            GenerateWhereStatement(where, sb, parameters);
            GenerateGroupByStatement(groupBy, sb);
            GenerateHavingStatement(having, sb, parameters);
            GenerateOrderByStatement(orderBy, sb);

            return sb.ToString();
        }

        protected virtual void GenerateSelectStatement(SelectClause clause, bool distinct, int limit, int offset, StringBuilder sb)
        {
            sb.Append("SELECT ");

            if (distinct)
            {
                sb.Append("DISTINCT ");
            }

            if (clause.SelectColumns.Count == 0)
            {
                sb.Append("*");
            }
            else
            {
                foreach (SelectColumn column in clause.SelectColumns)
                {
                    GenerateSelectColumn(column, sb);
                    sb.Append(", ");
                }
                sb.Remove(sb.Length - 2, 2);
            }
        }

        protected virtual void GenerateSelectColumn(SelectColumn column, StringBuilder sb)
        {
            switch (column.Type)
            {
                case SelectType.Aggregate:
                    GenerateAggregate((string)column.NameOrExpression, sb);
                    break;
                case SelectType.Column:
                    GenerateColumnName((string)column.NameOrExpression, sb);
                    break;
            } 
            
            if (!string.IsNullOrEmpty(column.Alias))
            {
                sb.Append(" AS ");
                GenerateAliasName(column.Alias, sb);
            }
        }
    }
}
